package com.skyworth.web.common.controller;


import com.skyworth.web.admin.user.domain.UserModel;
import com.skyworth.web.common.Constants;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.UnauthorizedException;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RequestMethod;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


public class BaseController {
    Logger LOG = LoggerFactory.getLogger(BaseController.class);

    @Autowired
    private Environment env;

    /**
     * 获取session
     *
     * @return
     */
    public static Session getSession() {
        return SecurityUtils.getSubject().getSession();
    }

    /**
     * 获取当前登录的用户信息
     *
     * @return
     */
    public static UserModel currentUser() {
        /*UserModel currentUser = (UserModel) SecurityUtils.getSubject().getPrincipal();
        if (null == currentUser) {
            currentUser = (UserModel) getSession().getAttribute(Constants.SESSION_USER_KEY);
        }
        return currentUser;*/
        return (UserModel) getSession().getAttribute(Constants.SESSION_USER_KEY);
    }

    public static void setSessionAttribute(String key, Object obj) {
        Subject currentUser = SecurityUtils.getSubject();
        Session session = currentUser.getSession();
        session.setAttribute(key, obj);
    }

    public static Object getSessionAttribute(String key) {
        Subject currentUser = SecurityUtils.getSubject();
        Session session = currentUser.getSession();
        return session.getAttribute(key);
    }

    public static void setUserSession(UserModel user) {
        setSessionAttribute(Constants.SESSION_USER_KEY, user);
    }

    public static void setLoginToken(String token){
        setSessionAttribute(Constants.SESSION_TOKEN, token);
    }

    public Map<String, Object> responseMap() {
        Map<String, Object> map = new HashMap<>();
        map.put("success", true);
        map.put("message", "返回消息");
        return map;
    }

    /**
     * 基于@ExceptionHandler异常处理
     */
    @ExceptionHandler
    public String exp(HttpServletRequest request, Exception ex) {
        request.setAttribute("ex", ex);
        // 根据不同错误转向不同页面
        if (ex instanceof UnauthorizedException) {
            if(request.getMethod()== RequestMethod.GET.toString()) {
                return "error/403";
            }else {
                return "redirect:error/403";
            }
        } else {
            ex.printStackTrace();
            return "error/500";
        }
    }
   /* public boolean loginCheck(String token){
        HttpClient httpClient = new HttpClient();
        return true;
    }*/

    public boolean loginCheck(String token, HttpServletRequest request){
        HttpSession session = request.getSession();
        String sessToken = (String) session.getAttribute(Constants.SESSION_TOKEN);
        boolean ret = false;
        if(env.getProperty("product.level").equals("test")) {
            return true;
        }
        if(token==null || token.length()==0){
            LOG.error("token is missing");
            return false;
        }
        if(sessToken != null &&
                sessToken.equals(token)){
            return true;
        }

        String refer = request.getHeader("referer");
        LOG.info("refer is " + refer);
        String adminRefer = env.getProperty("admin.refer");
        String strUrl = env.getProperty("admin.url");
        if(adminRefer==null || strUrl==null){
            LOG.error("admin configures is missing");
            return ret;
        }

        if(refer==null || !refer.startsWith(adminRefer)){
            LOG.error("refer info is error");
            return ret;
        }
        strUrl += "?token="+token;
        URL url = null;
        BufferedReader in = null;
        String result = "";
        LOG.info("request url "+ strUrl);
        try {
            url = new URL(strUrl);
            URLConnection conn = url.openConnection();
            conn.setRequestProperty("accept", "*/*");
            conn.setRequestProperty("connection", "Keep-Alive");
            conn.setRequestProperty("user-agent", "skyworth");
            conn.connect();
            Map<String, List<String>> resHeader = conn.getHeaderFields();
            for(String key: resHeader.keySet()){
                LOG.info("response header: "+key+"--->"+resHeader.get(key));
            }
            in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
            String line ;
            while((line=in.readLine()) != null){
                result += line;
            }
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        finally {
            try {
                if (in != null) {
                    in.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        LOG.info("response body is "+ result);
        if(result.equals("ok")){
            ret = true;
            LOG.info("begin to save token "+ token);
            session.setAttribute(Constants.SESSION_TOKEN, token);
        }
        return ret;
    }

    public static String sendPost(String url, String param){
        PrintWriter out = null;
        BufferedReader in  = null;
        String result = "";

        try {
            URL realUrl = new URL(url);
            URLConnection conn = realUrl.openConnection();
            conn.setRequestProperty("accept", "*/*");
            conn.setRequestProperty("connection", "Keep-Alive");
            conn.setRequestProperty("user-agent", "Mozilla/4.0");

            conn.setDoOutput(true);
            conn.setDoInput(true);

            out = new PrintWriter(conn.getOutputStream());
            out.print(param);
            out.flush();

            in = new BufferedReader(
                    new InputStreamReader(conn.getInputStream())
            );

            String line ;
            while((line=in.readLine()) != null){
                result += line;
            }

        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        finally {
            try {
                if(out != null) {
                    out.close();
                }
                if(in != null) {
                    in.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return result;
    }

    protected boolean isLogin(UsernamePasswordToken token) {
        Subject currentUser = SecurityUtils.getSubject();
        if(currentUser==null){
            return false;
        }
            currentUser.login(token);
        return currentUser.isAuthenticated();
    }
}
